#include<stdio.h>
#include<string>
#include<queue>
#include<stack>
#include<map>
#include<iostream>

using std::string;  using std::map;
using std::stack;   using std::queue;
using std::cin;

typedef struct node
{
    double m_num;
    char m_op;
    bool m_flag;
}node;

string g_Str;
stack<node> g_S;
queue<node> g_Q;
map<int, char> g_Op;

void Change(){//中缀转后缀
    double num;
    node temp;
    for (string::size_type i = 0; i != g_Str.size();)
    {
        if(g_Str[i] >= '0' && g_Str[i] <= '9'){
            temp.m_flag = true; //标记是数字
            temp.m_num = g_Str[i++] - '0';//记录这个操作数的第一位
            while(i < g_Str.size() && g_Str[i] >= '0'&&  g_Str[i] <= '9'){//连续读入数字并按数位还原 原始数值
                temp.m_num = temp.m_num * 10 + (g_Str[i] - '0');
                i++;
            }
            g_Q.push(temp);//操作数压入后缀表达式队列
        }else{
            temp.m_flag = false;
            if(g_Str[i] == '(') {
                temp.m_op = g_Str[i];
                g_S.push(temp);//压入操作符栈
                i++;
            }else if(g_Str[i] == ')'){//一直弹出直到遇见左括号
                while(!g_S.empty() && (g_S.top().m_op != '(')){
                    g_Q.push(g_S.top());
                    g_S.pop();
                }
                g_S.pop();//把左括号也弹出
                i++;
            }else{
                //栈顶元素比操作符高，就把栈顶元素弹到后缀表达式中
                while(!g_S.empty() && g_Op[g_S.top().m_op] >= g_Op[g_Str[i]]){
                    g_Q.push(g_S.top());
                    g_S.pop();
                }
                temp.m_op = g_Str[i];
                g_S.push(temp);//压入操作符栈
                i++;
            }
        }
    }

    while(!g_S.empty()){//操作符栈中还有操作符弹到后缀表达队列中
        g_Q.push(g_S.top());
        g_S.pop();
    }

//        while(!g_Q.empty()) //打印后缀队列
//    {
//        if(g_Q.front().m_flag == true){
//            printf("%f ",g_Q.front().m_num);
//        }else{
//            printf("%c ", g_Q.front().m_op);
//        }
//        g_Q.pop();
//    }
//    printf("\n");
}

double Cal(){ //计算后缀表达式
    node cur, temp; //temp记录 弹出栈后计算得到值的信息
    double num1,num2;//存储从栈中弹出的两个数值
    while(!g_Q.empty()){
        cur  = g_Q.front();
        g_Q.pop();
        if(cur.m_flag == true) {
            g_S.push(cur);
        }else{
            num2 = g_S.top().m_num;//弹出第二个操作数
            g_S.pop();
            num1 = g_S.top().m_num;//弹出第一个操作数
            g_S.pop();
            temp.m_flag = true;//临时记录操作数为数字
            if(cur.m_op == '+') temp.m_num = num1 + num2;
            else if(cur.m_op == '-') temp.m_num = num1 - num2;
            else if(cur.m_op == '*') temp.m_num = num1 * num2;
            else temp.m_num = num1 / num2;
            g_S.push(temp);//把计算得到的结果（该操作数）压入栈
        }
    }
    return g_S.top().m_num;//栈顶元素就是后缀表达式的值
}


int pd_(){
    g_Op['+'] = g_Op['-'] = 1;
    g_Op['*'] = g_Op['/'] = 2;
    for (string::iterator it = g_Str.end(); it != g_Str.begin(); it--){
        if(*it == ' ') g_Str.erase(it);
    }
    while(!g_S.empty()) g_S.pop();//初始化栈，在下次计算开始时清空栈内容
    Change();
	std::cout<<Cal();
    return Cal();
}

int main(int argc, char const *argv[]){
	g_Str="11+(123+1)";
    // std::cout<<pd_();
	g_Op['+'] = g_Op['-'] = 1;
    g_Op['*'] = g_Op['/'] = 2;
    for (string::iterator it = g_Str.end(); it != g_Str.begin(); it--){
        if(*it == ' ') g_Str.erase(it);
    }
    while(!g_S.empty()) g_S.pop();//初始化栈，在下次计算开始时清空栈内容
    Change();
	std::cout<<Cal();
    return 0;
}
